﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace doubly_linked_list
{
    class KolejkaDwukierunkowa
    {
        private Item head;
        private Item tail;
        private int size;

        public KolejkaDwukierunkowa()
        {
            head = null;
            tail = null;
            size = 0;
        }

        public KolejkaDwukierunkowa(int n)
        {
            Item newItem = new Item(n);

            tail = newItem;
            newItem.next = head;
            head = newItem;
            size++;
        }

        public bool isEmpty()
        {
            return head == null;
        }

        public void insertFirst(int liczba)
        {
            Item newItem = new Item(liczba);

            if (isEmpty())
            {
                tail = newItem;
            }
            else
            {
                head.previous = newItem;
            }

            newItem.next = head;
            head = newItem;
            size++;
        }

        public void insertLast(int liczba)
        {
            Item newItem = new Item(liczba);
            if (isEmpty())
                head = newItem;
            else
            {
                tail.next = newItem;
                newItem.previous = tail;
            }
            tail = newItem;
            size++;
        }

        public Item deleteFirst()
        {
            Item temp = head;
            if (head.next == null)
                tail = null;
            else
                head.next.previous = null;
            head = head.next;
            size--;
            return temp;
        }

        public Item deleteLast()
        {
            Item temp = tail;
            if (head.next == null)
                head = null;
            else
                tail.previous.next = null;
            tail = tail.previous;
            size--;
            return temp;
        }

        public bool contains(int key)
        {
            Item current = head;

            while (current != null)
            {
                if (current.wartosc == key)
                {
                    Console.WriteLine("Kolejka zawiera wartosc: " + key);
                    return true;
                }

                current = current.next;
            }

            Console.WriteLine("Kolejka nie zawiera wartosci: " + key);
            return false;
        }

        public void sort()
        {
            for (int i = 0; i < size; i++)
            {
                Item currentNode = head;
                Item nextNode = currentNode != null ? currentNode.next : null;
                while (currentNode != null && nextNode != null)
                {
                    if (currentNode.wartosc > nextNode.wartosc)
                    {
                        swap(head, currentNode, nextNode);
                    }
                    else
                    {
                        currentNode = nextNode;
                    }
                    nextNode = currentNode.next;
                }
            }
        }

        public void swap(int a, int b)
        {
            Item currentItem = head;
            Item node1;
            Item node2;

            for (int i = 0; i < a; i++)
            {
                currentItem = currentItem.next;
            }
            node1 = currentItem;
            currentItem = head;

            for (int i = 0; i < b; i++)
            {
                currentItem = currentItem.next;
            }
            node2 = currentItem;

            swap(head, node1, node2);

        }

        public void swap(Item head, Item first, Item second)
        {
            int tempValue = first.wartosc;
            first.wartosc = second.wartosc;
            second.wartosc = tempValue;
        }

        public Item deleteKey(long key)
        {
            Item current = head;
            while (current.wartosc != key)
            {
                current = current.next;
                if (current == null)
                    return null;                           // nie można znaleźć
            }

            if (current == head)                           // znaleziono - pierwszy item
                head = current.next;
            else
                current.previous.next = current.next;

            if (current == tail)                           // czy ostatni item
                tail = current.previous;
            else                                           // nie ostatn
                current.next.previous = current.previous;
            size--;
            return current;                                // return item
        }

        public void displayElement(int numberOfElement)
        {
            Console.Write("Element kolejki o numerze " + numberOfElement + " (zaczynając od 0) wynosi: ");
            Item current = head;                            // zacznij od początku

            for (int i = 0; i < numberOfElement; i++)
            {
                current = current.next;
            }
            current.displayLink();
            Console.WriteLine();
        }

        public void displayForward()
        {
            Console.Write("Elementy listy ");
            Item current = head;                           // zacznij od początku

            while (current != null)                        // wykonuj do końca listy
            {
                current.displayLink();
                current = current.next;                    // przejdź do kolejnego itemu
            }
            Console.WriteLine();
        }

        public void displayBackward()
        {
            Console.WriteLine("List : ");
            Item current = tail;
            while (current != null)
            {
                current.displayLink();
                current = current.previous;
            }
            Console.WriteLine("");
        }
    }
}
